package com.petdog.common.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.mail.MailException;

import javax.mail.MessagingException;
import java.net.SocketTimeoutException;

/**
 * 邮件发送异常处理器
 * 处理邮件发送过程中的各种异常情况，提供降级策略
 */
@Component
public class MailSendExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(MailSendExceptionHandler.class);

    /**
     * 处理邮件发送异常
     * @param e 邮件发送异常
     * @return 是否成功处理异常（true表示已处理，可以继续程序流程）
     */
    public boolean handleException(Exception e) {
        if (e == null) {
            return true;
        }

        // 记录异常日志
        logger.error("邮件发送异常: {}", e.getMessage(), e);

        // 根据不同异常类型提供不同的处理策略
        if (e instanceof MailException) {
            return handleMailException((MailException) e);
        } else if (e instanceof MessagingException) {
            return handleMessagingException((MessagingException) e);
        } else if (e.getCause() instanceof SocketTimeoutException) {
            // 处理SMTP连接超时异常
            logger.warn("SMTP连接超时，请检查网络连接或邮件服务器配置");
            // 实际项目中可以考虑将邮件放入队列稍后重试
            return false; // 标记为未成功处理
        }

        // 其他未知异常
        logger.error("未知的邮件发送异常类型: {}", e.getClass().getName());
        return false;
    }

    /**
     * 处理Spring MailException
     */
    private boolean handleMailException(MailException e) {
        logger.error("Spring Mail异常: {}", e.getMessage());
        
        // 检查是否包含连接超时异常
        if (containsSocketTimeout(e)) {
            logger.warn("邮件发送连接超时，可能是网络问题或邮件服务器配置错误");
            return false;
        }
        
        return false;
    }

    /**
     * 处理JavaMail MessagingException
     */
    private boolean handleMessagingException(MessagingException e) {
        logger.error("JavaMail消息异常: {}", e.getMessage());
        
        // 检查是否包含连接超时异常
        if (containsSocketTimeout(e)) {
            logger.warn("邮件发送连接超时，可能是网络问题或邮件服务器配置错误");
            return false;
        }
        
        return false;
    }

    /**
     * 检查异常链中是否包含SocketTimeoutException
     */
    private boolean containsSocketTimeout(Throwable e) {
        if (e == null) {
            return false;
        }
        
        if (e instanceof SocketTimeoutException || 
            (e.getMessage() != null && e.getMessage().contains("timeout"))) {
            return true;
        }
        
        return containsSocketTimeout(e.getCause());
    }
}